package com.hyh.filter;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import com.hyh.dao.UserMapper;
import com.hyh.util.JwtUtil;
import com.hyh.util.RedisCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

@Order(-21)
@Component
public class GlobalFilterAuthentication implements  GlobalFilter {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        String token = headers.getFirst("token");


        if(request.getURI().getPath().contains("/api/user/login") ||
                request.getURI().getPath().contains("/api/user/sendCode") ||
                request.getURI().getPath().contains("/api/user/uploadAvatar/") ||
                request.getURI().getPath().contains("/api/user/**")){
            // 放行
            return chain.filter(exchange);
        }

        Long userId = null;
        if(token == null || token.isEmpty()){
            // 拦截请求
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return out(exchange.getResponse());
        }
        try{
            userId = Long.valueOf(JwtUtil.verify(token).getClaim("id").asString());
        }
        catch (Exception e) {
            e.printStackTrace();
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return out(exchange.getResponse());
        }
        if(userMapper.selectById(userId) != null){
            // 放行
            // 刷新redis中的token number 和用户信息
            stringRedisTemplate.expire(RedisCodeUtil.TOKEN+userId,
                    RedisCodeUtil.EXPIRE_TIME, TimeUnit.MINUTES);
            stringRedisTemplate.expire(RedisCodeUtil.NUMBER+userId,
                    RedisCodeUtil.EXPIRE_TIME, TimeUnit.MINUTES);
            stringRedisTemplate.expire(RedisCodeUtil.USER + token,
                    RedisCodeUtil.EXPIRE_TIME, TimeUnit.MINUTES);
            stringRedisTemplate.expire(RedisCodeUtil.LOGIN_USER_AUTH_KEY + userId,
                    RedisCodeUtil.EXPIRE_TIME, TimeUnit.MINUTES);
            return chain.filter(exchange);
        }
        // 拦截请求
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return out(exchange.getResponse());
    }
    private Mono<Void> out(ServerHttpResponse response) {
        JsonObject message = new JsonObject();
        message.addProperty("status", false);
        message.addProperty("code", HttpStatus.UNAUTHORIZED.value());
        message.addProperty("data", "鉴权失败");
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定编码，否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}
